package org.middleware.service.system;

import org.middleware.common.BusinessException;
import org.middleware.dao.system.SysMenusDao;
import org.middleware.entity.system.SysMenus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @author zhiqiangwu
 * @description 针对表【sys_menus(菜单表)】的数据库操作Service
 * @createDate 2025-09-05 16:40:01
 */
@Service
public class SysMenusService {
    @Autowired
    private SysMenusDao menusDao;

    /**
     * 根据系统id和父菜单id查询菜单
     *
     * @param system_id 系统id
     * @param parent_id 父菜单id
     * @return 所有菜单列表
     */
    public List<SysMenus> getMenusBySysAndParent(int system_id, int parent_id, String name) {
        if (system_id < 0) {
            throw new BusinessException("系统id参数非法");
        }
        if (parent_id < 0) {
            throw new BusinessException("父菜单id参数非法");
        }
        List<SysMenus> allSystemsMenus = menusDao.getMenusBySysAndParent(system_id, -1, name);
        // 前端已经处理菜单树了，后端就不处理了，性能影响不大，就先不注释了
        List<SysMenus> menuTree = buildMenuTree(allSystemsMenus, 0);
        return allSystemsMenus;
    }

    private List<SysMenus> buildMenuTree(List<SysMenus> menuList, int parent_id) {
        List<SysMenus> tree = new ArrayList<>();
        for (SysMenus menu : menuList) {
            if (parent_id == menu.getParentId()) {
                List<SysMenus> children = buildMenuTree(menuList, menu.getId());
                menu.setChildren(children);
                tree.add(menu);
            }
        }
        if (tree.size() > 0) {
            // 按排序字段排序
            tree.sort(Comparator.comparingInt(SysMenus::getSort));
        }
        return tree;
    }

    /**
     * 根据系统id查询菜单
     *
     * @param system 系统id
     * @return 树形菜单数据，包含children
     */
    public List<SysMenus> getMenuTreeBySystem(int system) {
        if (system < 0) {
            throw new BusinessException("系统id参数非法");
        }
        List<SysMenus> allSystemsMenus = menusDao.getMenusBySysAndParent(system, -1, "");
        List<SysMenus> menuTree = buildMenuTree(allSystemsMenus, 0);
        return menuTree;
    }

    /**
     * 新增菜单
     *
     * @param menu 菜单信息
     * @return 数据库操作记录数
     */
    public int create(SysMenus menu) {
        if (menu == null) {
            throw new BusinessException("菜单信息有误");
        }
        if (menu.getParentId() == null || "".equals(menu.getParentId())) {
            menu.setParentId(0);
        }
        if (menu.getSort() == null || "".equals(menu.getSort())) {
            menu.setSort(0);
        }
        return menusDao.create(menu);
    }

    /**
     * 修改菜单
     *
     * @param menu 菜单信息
     * @return
     */
    public int update(SysMenus menu) {
        if (menu == null || menu.getId() <= 0) {
            throw new BusinessException("菜单信息有误");
        }
        List<SysMenus> menus = menusDao.getMenusBySysAndParent(0, 0, "");
        List<Integer> list = needDeleteMenuIdArray(menu.getId(), menus);
        if (menu.getParentId() > 0 && list.contains(menu.getParentId())) {
            // 父菜单不为第一层，判断是否选了子菜单作为父菜单
            throw new BusinessException("不能选子菜单作为父菜单");
        }
        return menusDao.update(menu);
    }

    public int deleteAllSubMenus(int id) {
        if (id <= 0) {
            throw new BusinessException("菜单id参数错误");
        }
        List<SysMenus> menus = menusDao.getMenusBySysAndParent(0, 0, "");
        List<Integer> children = needDeleteMenuIdArray(id, menus);
        return menusDao.deleteAllSubMenus(children);
    }

    /**
     * 递归查询需要删除的菜单id
     * @param id
     * @param menuList
     * @return
     */
    private List<Integer> needDeleteMenuIdArray(int id, List<SysMenus> menuList) {
        List<Integer> result = new ArrayList<>();
        result.add(id);
        for(SysMenus menu : menuList) {
            if (menu.getParentId() == id) {
                result.addAll(needDeleteMenuIdArray(menu.getId(), menuList));
            }
        }
        return result;
    }


}
